package icu.d4peng.cloud.common.core.util;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.core.env.Environment;
import org.springframework.util.Assert;

/**
 * @author d4peng
 * @version 1.0.0
 * @date 2021-12-24 10:12
 * @description SpringIocUtils:IOC操作容器
 */
public class SpringIocUtils implements BeanFactoryAware {
    private static final Logger LOGGER = LoggerFactory.getLogger(SpringIocUtils.class);

    private static ApplicationContext applicationContext = null;
    private static DefaultListableBeanFactory defaultListableBeanFactory = null;

    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        Assert.notNull(beanFactory, "bean factory can't be null");
        SpringIocUtils.defaultListableBeanFactory = (DefaultListableBeanFactory) beanFactory;
    }

    public static DefaultListableBeanFactory getBeanFactory() {
        return defaultListableBeanFactory;
    }

    /**
     * 获得bean对象
     *
     * @param clazz bean类
     * @param <T>   bean类型
     * @return bean对象
     */
    public static <T> T getBean(Class<T> clazz) {
        return getBeanFactory().getBean(clazz);
    }

    /**
     * 获得bean对象
     *
     * @param beanName bean名称
     * @param <T>      bean类型
     * @return bean对象
     */
    @SuppressWarnings("unchecked")
    public static <T> T getBean(String beanName) {
        return (T) getBeanFactory().getBean(beanName);
    }

    /**
     * 获得bean对象
     *
     * @param name  bean名称
     * @param clazz bean类
     * @param <T>   bean类型
     * @return bean对象
     */
    public static <T> T getBean(String name, Class<T> clazz) {
        return getBeanFactory().getBean(name, clazz);
    }

    /**
     * 注册Bean
     *
     * @param beanName bean名称
     * @param bean     类型
     * @param <T>      bean类型
     */
    public static <T> void registerBean(String beanName, T bean) {
        DefaultListableBeanFactory factory = getBeanFactory();
        factory.autowireBean(bean);
        factory.registerSingleton(beanName, bean);
    }

    /**
     * 注销bean,将Spring中的bean注销，请谨慎使用
     *
     * @param beanName bean名称
     */
    public static void unregisterBean(String beanName) {
        DefaultListableBeanFactory factory = getBeanFactory();
        factory.destroyBean(beanName);
    }

    /**
     * 获得环境变量
     *
     * @return 环境变量
     */
    public static Environment getEnvironment() {
        return getBean(Environment.class);
    }

    /**
     * 获得某个环境变量的值
     *
     * @param key 环境变量名称
     * @return 变量的值
     */
    public static String getEnvironmentProperty(String key) {
        Environment environment = getEnvironment();
        return environment.getProperty(key);
    }


}